package com.yf.serviceImpl;

import com.alibaba.fastjson.JSONObject;
import com.yf.service.CommonService;
import com.yf.service.RedisService;
import com.yf.utils.HttpUtil;
import com.yf.utils.SendEmail;
import com.yf.utils.UserContext;
import com.yf.utils.Utils;
import lombok.extern.log4j.Log4j2;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.mail.javamail.JavaMailSenderImpl;
import org.springframework.mail.javamail.MimeMessageHelper;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import javax.mail.internet.MimeMessage;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Log4j2
@Service("CommonServiceImpl")
public class CommonServiceImpl implements CommonService {
    @Value("${custom.image-base}")
    private String ImageBase;

    @Value("${custom.imageBaseUri}")
    private String imageBaseUri;

    private static final Integer imageSizeThreshold = 5 * 1024 * 1024;

    // for recaptcha validation
    private static final String secret = "6LfPlUMfAAAAANWA1LW2BB1iig1v64l7-tpkzcXT";
    private static final String RECAPTCHA_VERIFY_SITE = "https://www.recaptcha.net/recaptcha/api/siteverify";
    private static final float threshold = 0.85f;

    // for send email
    @Autowired
    JavaMailSenderImpl sender;

    @Autowired
    RedisService redisService;

    @Value("${spring.mail.username}")
    private String username;

    private static final String subject = "dypi.xyz-邮箱验证";
    private static final String template = "验证地址为: https://dypi.xyz/register/activate?token=";

    private Map<String, Object> makeUploadImageResponse(String errorFile, String successFile, String path) {
        Map<String, Object> res = new HashMap<>(4);
        List<String> failed = new ArrayList<>(1);
        Map<String, String> success = new HashMap<>(4);
        if (errorFile != null && errorFile.length() > 0) {
            failed.add(errorFile);
        }
        if (successFile != null && successFile.length() > 0) {
            success.put(successFile, path);
        }
        res.put("errFiles", failed);
        res.put("succMap", success);
        return res;
    }

    @Override
    public Map<String, Object> uploadImage(MultipartFile file) {
        if (file == null) {
            return makeUploadImageResponse("nullFile", null, null);
        }

        String originName = file.getOriginalFilename();
        if (originName == null || originName.length() == 0) {
            return makeUploadImageResponse("empty", null, null);
        }
        final String[] split = originName.split("\\.");
        if (split.length < 2) {
            return makeUploadImageResponse("unknown", null, null);
        }
        Integer uid = UserContext.getUserId();
        String filename = String.format("%s@%d.%s", Utils.randomStr(12), uid, split[1]);
        if (file.getSize() > imageSizeThreshold) {
            return makeUploadImageResponse(filename, null, null);
        }
        String savePath = String.format("%s/%s", ImageBase, filename);
        String uri = String.format("%s/%s", imageBaseUri, filename);
        File dest = new File(savePath);
        try {
            file.transferTo(dest);
            return makeUploadImageResponse(null, filename, uri);
        } catch (IOException e) {
//            System.out.println(e);
            return makeUploadImageResponse(filename, null, null);
        }
    }

    @Override
    public boolean validateRecaptcha(String token) {
        String url = String.format("%s?secret=%s&response=%s", RECAPTCHA_VERIFY_SITE, secret, token);
        String resp = HttpUtil.post(url);
        if (Utils.isNullOrEmpty(resp)) {
            return false;
        }
        JSONObject parse = JSONObject.parseObject(resp);
        Boolean success = parse.getBoolean("success");
        log.info("success:" + success);
        if (success == null || !success) {
            return false;
        }
        Float score = parse.getFloat("score");
        log.info("score:" + score);
        if (score == null || score < threshold) {
            return false;
        }
        return true;
    }

    @Override
    public boolean sendActivateEmail(String receiver, String activateCode) {
        try {
            final MimeMessage message = sender.createMimeMessage();
            final MimeMessageHelper helper = new MimeMessageHelper(message);
            helper.setFrom(username);
            helper.setTo(receiver);
            helper.setSubject(subject);
            helper.setText(String.format("%s%s", template, activateCode));
            sender.send(helper.getMimeMessage());
            return true;
        } catch (Exception ignore) {
            return false;
        }
    }

    @Override
    public int sendEmailValidCode(String receiver) {
        if (redisService.existKey(receiver)) {
            return 1;
        }
        final String validCode = Utils.genValidCode(6);
        String subject = "dypi.xyz-验证码";
        String content = String.format("验证码:%s", validCode);
        try {
            if (SendEmail.sendEmail(receiver, subject, content)) {
                redisService.setKey(receiver, validCode, 1800);
                return 0;
            }
        } catch (Exception e) {
            log.error(e);
        }
        return 2;
    }
}
